package com.szxx.suit.superbomb;

import java.util.LinkedList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.szxx.constant.DdzCardTypes;
import com.szxx.domain.Card;
import com.szxx.domain.Cards;
import com.szxx.domain.DdzCard;
import com.szxx.suit.AbstractSuitTerm;
import com.szxx.suit.AbstractSuitType;
import com.szxx.suit.DdzAnalysisResult;
import com.szxx.suit.DdzSuitAnalyzer;
import com.szxx.suit.DdzTypeUtil;

/**
 * 炸弹牌型 <br>
 *
 * @author Ambrose
 */
@Component
public class SuperBombTypeAnalyzer extends DdzSuitAnalyzer {

	@Override
	public AbstractSuitType getSuitType() {
		return DdzCardTypes.SUPER_BOMB;
	}
	
	@Override
	protected DdzAnalysisResult getSuitResult() {
		DdzAnalysisResult result = new SuperBombAnalysisResult();
		result.setType(getSuitType());
		return result;
	}

	/** 关键数量 */
	private static int LIMIT_SIZE = 5;
	
	@Override
	public boolean doCheckRule(Cards cards, AbstractSuitTerm term, DdzAnalysisResult result) {
		if (result.getCardNum() >= LIMIT_SIZE) {
			if (result.isAllCardLazi()) {
				return true;
			} else {
				List<Integer> allValues = result.getNoneLaziValueCounter().getAllValues();
				return allValues.size() == 1 
						&& !result.getNoneLaziValueCounter().hasJoker(); // 只有一种点数
			}
		} else {
			return false;
		}
	}
	
	/**
	 * 填充癞子，仅当牌中含有癞子，且不全是癞子的时候会进入这里
	 * 
	 * @param cards
	 * @param term
	 * @param onlyMaxValue 仅赋值最大
	 */
	protected List<Cards> doAnalysizeLaizi(Cards cards, AbstractSuitTerm term, boolean onlyMaxValue) {
		List<Cards> cardsResult = new LinkedList<Cards>();
		DdzAnalysisResult result = (DdzAnalysisResult) cards.getResult();
		int value = result.getNoneLaziValueCounter().getAllValues().get(0).intValue();
		for (Card card : cards) {
			((DdzCard) card).changeCard(value);
		}
		Cards cardsCopy = cards.clone();
		analysize(cardsCopy, term);
		cardsResult.add(cardsCopy);
		return cardsResult;
	}
	
	@Override
	protected boolean containsPossibleCards(Cards handCards, AbstractSuitTerm term) {
		DdzAnalysisResult result = (DdzAnalysisResult) handCards.getResult();
		if (result.getCardNum() >= LIMIT_SIZE) {
			List<Integer> noneLaiziValues = result.getNoneLaziValueCounter().getAllValues();
			int maxValueNum= 0;
			for (Integer valueTemp : noneLaiziValues) {
				int valueTempNum = result.getNoneLaziValueCounter().getValueCount(valueTemp);
				if (valueTempNum > maxValueNum) {
					maxValueNum = valueTempNum;
				}
			}
			// 炸弹数量足够
			return result.getLaziCardNum() > 0 && result.getLaziCardNum() + maxValueNum >= LIMIT_SIZE;
		} else {
			return false;
		}
	}
	
	/** 最多使用癞子的数量 */
	private static int MAX_USE_LAIZI_CARD_NUM = 8;
	
	@Override
	protected List<Cards> doListPossibleCards(Cards handCards, AbstractSuitTerm term) {
		List<Cards> cardsResult = new LinkedList<Cards>();
		// 非癞子部分
		DdzAnalysisResult result = (DdzAnalysisResult) handCards.getResult();
		List<Card> noneLaiziCardList = handCards.subList(0, result.getNoneCardNum());
		Cards noneLaiziCards = DdzTypeUtil.createCardsCopy(noneLaiziCardList);
		noneLaiziCards.setResult(handCards.getResult().clone());
		// 癞子部分
		List<Card> laiziCardList = handCards.subList(result.getNoneCardNum(), result.getCardNum());
		Cards laiziCards = DdzTypeUtil.createCardsCopy(laiziCardList);
		laiziCards.setResult(handCards.getResult().clone());
		
		int laiziCardNum = result.getLaziCardNum();
		int maxUseLaiziCardNum = MAX_USE_LAIZI_CARD_NUM < laiziCardNum ? MAX_USE_LAIZI_CARD_NUM : laiziCardNum;
		for (int useLaiziCardNum = 1; useLaiziCardNum <= maxUseLaiziCardNum; useLaiziCardNum++) {
			List<Card> useLaiziCardList = DdzTypeUtil.cloneSublistedCards(laiziCards, 0, useLaiziCardNum);// 补癞子
			int minNeedCardNum = LIMIT_SIZE - useLaiziCardNum;
			if (minNeedCardNum > 0) { // 非纯癞子炸弹
				for (int needCardNum = minNeedCardNum; needCardNum <= 4; needCardNum++) { // 补2张可以是炸弹，那么3,4张也可以
					List<Cards> cardsList = new LinkedList<Cards>();
					if (needCardNum == 1) {
						cardsList.addAll(DdzTypeUtil.selectSingleCards(noneLaiziCards, false));
					} else {
						cardsList.addAll(DdzTypeUtil.selectTupleCountCards(noneLaiziCards, needCardNum));
					}
					for (Cards usecards : cardsList) {
						Card card = usecards.get(0);
						for (Card laiziCard : useLaiziCardList) {
							((DdzCard)laiziCard).changeCard(card.getValue());
						}
						Cards cardsCopy = DdzTypeUtil.cloneCardsAndAddCardList(usecards, useLaiziCardList);
						if (match(cardsCopy, term)) {
							analysize(cardsCopy, term);
							cardsResult.add(cardsCopy);
						}
					}
				}
			} else { // 纯癞子炸弹
				Cards AllLaiziCardsCopy = DdzTypeUtil.createCardsCopy(useLaiziCardList);
				if (match(AllLaiziCardsCopy, term)) {
					analysize(AllLaiziCardsCopy, term);
					cardsResult.add(AllLaiziCardsCopy);
				}
				// 任意牌都能组成炸弹
				for (int needCardNum = 1; needCardNum <= 4; needCardNum++) {
					List<Cards> cardsList = new LinkedList<Cards>();
					if (needCardNum == 1) {
						cardsList.addAll(DdzTypeUtil.selectSingleCards(noneLaiziCards, false));
					} else {
						cardsList.addAll(DdzTypeUtil.selectTupleCountCards(noneLaiziCards, needCardNum));
					}
					for (Cards usecards : cardsList) {
						Card card = usecards.get(0);
						for (Card laiziCard : useLaiziCardList) {
							((DdzCard)laiziCard).changeCard(card.getValue());
						}
						Cards cardsCopy = DdzTypeUtil.cloneCardsAndAddCardList(usecards, useLaiziCardList);
						if (match(cardsCopy, term)) {
							analysize(cardsCopy, term);
							cardsResult.add(cardsCopy);
						}
					}
				}
			}
		}
		return cardsResult;
	}
	
}
